<!--
 * @Description: 密码强度检测
 * @version: 1.0
-->
<template>
  <div class="dx-password-strength">
    <div class="dx-password-strength-bar" :class="`dx-password-strength-level-${level}`"></div>
  </div>
</template>
<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'

const level = ref<number>(0)
const props = withDefaults(defineProps<{ modelValue: string }>(), { modelValue: '' })

onMounted(() => strength(props.modelValue))
watch(
  () => props.modelValue,
  () => strength(props.modelValue)
)
// 检测密码强度
const strength = (v: string) => {
  let _level = 0
  //长度
  let has_length = v.length >= 6
  //包含数字
  let has_number = /\d/.test(v)
  //包含小写英文
  let has_lowercase = /[a-z]/.test(v)
  //包含大写英文
  let has_uppercase = /[A-Z]/.test(v)
  //没有连续的字符3位
  let no_continuity = !/(\w)\1{2}/.test(v)
  //包含特殊字符
  let has_special = /[`~!@#$%^&*()_+<>?:"{},./;'[\]]/.test(v)

  if (v.length <= 0) {
    _level = 0
    level.value = _level
    return false
  }
  if (!has_length) {
    _level = 1
    level.value = _level
    return false
  }
  if (has_number) {
    _level += 1
  }
  if (has_lowercase) {
    _level += 1
  }
  if (has_uppercase) {
    _level += 1
  }
  if (no_continuity) {
    _level += 1
  }
  if (has_special) {
    _level += 1
  }
  level.value = _level
}
</script>

<style scoped lang="scss">
.dx-password-strength {
  height: 5px;
  width: 100%;
  background: var(--el-color-info-light-5);
  border-radius: 5px;
  position: relative;
  margin: 10px 0;

  &:before {
    left: 20%;
  }

  &:after {
    right: 20%;
  }

  &:before,
  &:after {
    position: absolute;
    content: '';
    display: block;
    width: 20%;
    height: inherit;
    border: 5px solid var(--el-bg-color-overlay);
    border-top: 0;
    border-bottom: 0;
    z-index: 1;
    background-color: transparent;
    box-sizing: border-box;
  }
}

$strength-levels: (
  1: (
    width: 20%,
    background-color: var(--el-color-error)
  ),
  2: (
    width: 40%,
    background-color: var(--el-color-error)
  ),
  3: (
    width: 60%,
    background-color: var(--el-color-warning)
  ),
  4: (
    width: 80%,
    background-color: var(--el-color-success)
  ),
  5: (
    width: 100%,
    background-color: var(--el-color-success)
  )
);

.dx-password-strength-bar {
  position: absolute;
  height: inherit;
  width: 0%;
  border-radius: inherit;
  transition:
    width 0.5s ease-in-out,
    background 0.25s;
  background: transparent;

  @each $level, $properties in $strength-levels {
    &.dx-password-strength-level-#{$level} {
      @each $property, $value in $properties {
        #{$property}: $value;
      }
    }
  }
}
</style>
